#include "CWindowBar.h"
#include "CMenuBar.h"
#include "Managers/DataManager.h"
#include "Private/CWindowBarTitleLabel.h"

#include <QApplication>
#include <QPainter>
#include <QRandomGenerator>

CWindowBar::CWindowBar(QWidget *parent) : CBaseTitleBar(parent) {
    init();
}

CWindowBar::~CWindowBar() {
}

void CWindowBar::reloadStrings() {
    m_minButton->setToolTip(tr("Minimize"));
    m_closeButton->setToolTip(tr("Close"));
    reloadMaxButtonState();
}

void CWindowBar::init() {
    setAttribute(Qt::WA_StyledBackground);

    m_iconButton = new CToolButton();
    m_iconButton->setObjectName("icon-button");

    m_titleLabel = new CWindowBarTitleLabel();
    m_titleLabel->setObjectName("win-title-label");
    m_titleLabel->installEventFilter(this);

    m_minButton = new CToolButton();
    m_maxButton = new CToolButton();
    m_closeButton = new CToolButton();

    m_minButton->setObjectName("min-button");
    m_maxButton->setObjectName("max-button");
    m_closeButton->setObjectName("win-close-button");

    m_titleLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    m_iconButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    m_minButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    m_maxButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    m_closeButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);

    m_spacerLeft = new QSpacerItem(40, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
    m_spacerRight = new QSpacerItem(40, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);

    m_menuBar = new CMenuBar();
    m_menuBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);

    m_layout = new QHBoxLayout();
    m_layout->setMargin(0);
    m_layout->setSpacing(0);
    m_layout->addWidget(m_iconButton);
    m_layout->addWidget(m_menuBar);
    m_layout->addItem(m_spacerLeft);
    m_layout->addWidget(m_titleLabel);
    m_layout->addItem(m_spacerRight);
    m_layout->addWidget(m_minButton);
    m_layout->addWidget(m_maxButton);
    m_layout->addWidget(m_closeButton);

    setLayout(m_layout);
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);

    m_titleLabel->setText(windowTitle());
    m_maxButton->setCheckable(true);

    connect(m_minButton, &QAbstractButton::clicked, this, &CWindowBar::handleMinimize);
    connect(m_maxButton, &QAbstractButton::clicked, this, &CWindowBar::handleMaximize);
    connect(m_closeButton, &QAbstractButton::clicked, this, &CWindowBar::handleClose);
    connect(this, &QWidget::windowTitleChanged, this, &CWindowBar::handleWindowTitleChanged);

    Q_TR_NOTIFY(CWindowBar)
}

QMenuBar *CWindowBar::menuBar() const {
    return m_menuBar;
}

void CWindowBar::setMenuBar(QMenuBar *menuBar) {
    auto *oldItem = m_layout->replaceWidget(m_menuBar, menuBar);
    delete oldItem;
    delete m_menuBar;
    m_menuBar = menuBar;
}

bool CWindowBar::isMouseFree() const {
    QPoint pos = mapFromGlobal(QCursor::pos());
    QWidget *w = childAt(pos);
    if ((!w && rect().contains(pos)) || w == m_titleLabel || w == m_iconButton) {
        return true;
    }
    return false;
}

void CWindowBar::reloadMaxButtonState() {
    if (window()->windowState() == Qt::WindowMaximized) {
        m_maxButton->setChecked(true);
        m_maxButton->setToolTip(tr("Restore%1").arg(""));
    } else {
        m_maxButton->setChecked(false);
        m_maxButton->setToolTip(tr("Maximize"));
    }
}

void CWindowBar::handleMinimize() {
    emit minRequested();
}

void CWindowBar::handleMaximize() {
    emit maxRequested();
}

void CWindowBar::handleClose() {
    emit closeRequested();
}

void CWindowBar::handleWindowTitleChanged(const QString &title) {
    m_titleLabel->setText(title);
}

void CWindowBar::drawCentralTitle(QPainter &painter) {
    QString title = m_titleLabel->text();
    QFontMetrics font(m_titleLabel->font());
    int fontWidth = font.horizontalAdvance(title);
    int viewWidth = m_titleLabel->width();
    if (fontWidth > viewWidth) {
        title = font.elidedText(title, Qt::ElideRight, viewWidth);
    }
    int expectLeft = (width() - viewWidth) / 2;
    QRect leftRect = m_spacerLeft->geometry();
    QSize minSize = m_spacerLeft->sizeHint();
    if (expectLeft < leftRect.left() + minSize.width()) {
        expectLeft = m_titleLabel->x();
    }
    QRect rect(expectLeft, m_titleLabel->y(), m_titleLabel->width(), m_titleLabel->height());
    painter.setPen(QPen(m_titleColor));
    painter.setFont(m_titleLabel->font());
    painter.drawText(rect, Qt::AlignCenter, title);
}

void CWindowBar::updateBarVisible() {
    m_iconButton->setVisible(m_barVisible);
    m_minButton->setVisible(m_barVisible);
    m_maxButton->setVisible(m_barVisible);
    m_titleLabel->setVisible(m_barVisible);
    m_closeButton->setVisible(m_barVisible);
}

void CWindowBar::paintEvent(QPaintEvent *event) {
    QPainter painter(this);
    painter.setClipRegion(event->region());
    painter.setRenderHint(QPainter::Antialiasing);
    if (m_barVisible) {
        drawCentralTitle(painter);
    }
}
